
##***************************************************************************
## SoilTexture
## A QGIS plugin
## Define soil texture from sand and clay raster maps
##                             -------------------
## begin                : 2010-11-14
## copyright            : (C) 2010 by Gianluca Massei
## email                : g_massa@libero.it
## **************************************************************************
#-----------------------------------------------------------
#
# licensed under the terms of GNU GPL 2
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, print to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#---------------------------------------------------------------------

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from ui_roughsetmcda import Ui_RoughSetMCDA

import os, sys, time
from osgeo import gdal, ogr
from osgeo.gdalconst import *

import numpy as np
import matplotlib.nxutils as nx
import fnmatch

class RoughSetMCDADialog(QDialog, Ui_RoughSetMCDA):

    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)
        self.connect(self.toolButtonAttributesGain, SIGNAL("clicked()"), self.InputAttributesGain)
        self.connect(self.toolButtonAttributesCost, SIGNAL("clicked()"), self.InputAttributesCost)
        self.connect(self.toolButtonDecision, SIGNAL("clicked()"), self.InputDecision)
        self.connect(self.toolButtonClassified, SIGNAL("clicked()"), self.OutputClassified)
        self.connect(self.toolButtonTextOut, SIGNAL("clicked()"), self.OutputText)

        self.connect(self.buttonBox, SIGNAL("accepted()"),self.accept)
        QObject.connect(self.buttonBox, SIGNAL("rejected()"),self, SLOT("reject()"))

        mapCanvas = self.iface.mapCanvas()
        # init dictionaries of items:

    def InputAttributesGain(self):
        "Display file dialog for input attributes gain"
        self.lineEditAttributesGain.clear()
        AttributesGain = QFileDialog.getOpenFileNames(self, "attributes input files",".", "GeoTiff (*.tif)")
        if not AttributesGain.isEmpty():
            self.lineEditAttributesGain.clear()
            self.lineEditAttributesGain.insert(AttributesGain.join(","))

        return AttributesGain

    def InputAttributesCost(self):
        "Display file dialog for input attributes cost"
        self.lineEditAttributesCost.clear()
        AttributesCost = QFileDialog.getOpenFileNames(self, "attributes input files",".", "GeoTiff (*.tif)")
        if not AttributesCost.isEmpty():
            self.lineEditAttributesCost.clear()
            self.lineEditAttributesCost.insert(AttributesCost.join(","))
        return AttributesCost

    def InputDecision(self):
        "Display file dialog for input decision areas"
        self.lineEditDecision.clear()
        Decision = QFileDialog.getOpenFileName(self, "decision input file",".", "GeoTiff (*.tif)")
        if not Decision.isEmpty():
            self.lineEditDecision.clear()
            self.lineEditDecision.insert(Decision)
        return Decision

    def OutputClassified(self):
        "Display file dialog for output  classified map"
        self.lineEditClassifiedMap.clear()
        OutputMap = QFileDialog.getSaveFileName(self, "Output map file",".", "GeoTiff (*.tif)")
        if not OutputMap.isEmpty():
            self.lineEditClassifiedMap.clear()
            self.lineEditClassifiedMap.insert(OutputMap)
        return OutputMap

    def OutputText(self):
        "Display file dialog for output  text file"
        self.lineEditTextOut.clear()
        OutputText = QFileDialog.getSaveFileName(self, "Output text files",".", "text file")
        if not OutputText.isEmpty():
            self.lineEditTextOut.clear()
            self.lineEditTextOut.insert(OutputText)
        return OutputText

    def ProcessRaster(self,raster):
        "Register all of the GDAL drivers"
        gdal.AllRegister()
        # open the image
        raster=str(raster)

        imgRaster = gdal.Open(raster,GA_ReadOnly)
        if imgRaster is None:
            QMessageBox.information(None,"Exiting gracefully","Could not open raster %s!" % raster)

        # get image size
        rows = imgRaster.RasterYSize
        cols = imgRaster.RasterXSize
        bands = imgRaster.RasterCount
        if bands >1:
            QMessageBox.information(None,"Exiting gracefully","Raster %s has %d bands!" % (raster,bands))

        # get georeference info
        transform = imgRaster.GetGeoTransform()
        xOrigin = transform[0]
        yOrigin = transform[3]
        pixelWidth = transform[1]
        pixelHeight = transform[5]

        dataRaster = imgRaster.ReadAsArray()
        return dataRaster


    def BuildFileISF(self,AttributesGain, AttributesCost, Decision, outputMap):

        AttributesGain=AttributesGain.split(',')
        AttributesCost=AttributesCost.split(',')

        dataAttributesGain=[self.ProcessRaster(attribute) for attribute in AttributesGain]
        dataAttributesCost=[self.ProcessRaster(attribute) for attribute in AttributesCost]
        dataAttributes=dataAttributesGain+dataAttributesCost

        dataDecision=self.ProcessRaster(Decision)

        self.textEditLog.append(str(type(dataDecision)))
        self.textEditLog.append(str(type(dataAttributes)))

        outputTxt=self.lineEditTextOut.text()
        outf = file(outputTxt,"w")
        outf.write("**ATTRIBUTES\n")

        for i in range(len(AttributesGain)):
            outf.write("+ %s: (continuous)\n" % AttributesGain[i])
        for i in range(len(AttributesCost)):
            outf.write("+ %s: (continuous)\n" % AttributesCost[i])

        values=reduce(set.union, map(set,dataDecision))
        values=','.join(str(v) for v in values)
        outf.write("+ %s: [%s]" % (Decision,values))

        outf.write("\ndecision: %s\n" % Decision)

        outf.write("\n**PREFERENCES\n")
        for f in AttributesGain:
            outf.write("%s: gain\n" % f)
        for f in AttributesCost:
            outf.write("%s: cost\n" % f)

        outf.write("\n**EXAMPLES\n")


        self.textEditLog.append(str(type(dataAttributes)))
        #MATRIX=[data for data in dataAttributes if dataDecision is not None ]
        MATRIX=np.array(dataAttributes)
        dim=np.shape(MATRIX)
        self.textEditLog.append(str(dim))

        for d in range(dim[0]):
            for r in range(dim[1]):
                for c in range(dim[2]):
                    outf.write(" %d " % (MATRIX[d][r][c]))
                outf.write(" \n" )
        outf.write("**END")
        dim=len(MATRIX),len(MATRIX[d]),len(MATRIX[d][r]),
        self.textEditLog.append(str(dim))
        outf.close()
        return outputTxt


    def writeTextureGeoTiff(self,arrayData, transform, rows, cols, outFile):
        "Write the given array data to the file 'outfile' with the given extent."
        try:
            format = "GTiff"
            driver = gdal.GetDriverByName( format )
            NOVALUE=-9999
            metadata = driver.GetMetadata()
            if metadata.has_key(gdal.DCAP_CREATE) \
                   and metadata[gdal.DCAP_CREATE] == 'YES':
                pass
            else:
                QMessageBox.information(None,"info","Driver %s does not support Create() method." % format)
                return False
            outDataset = driver.Create(str(outFile), cols, rows, 1, gdal.GDT_Byte)
            outTexture=outDataset.GetRasterBand(1)
            outTexture.WriteArray(arrayData)
            outTexture.SetNoDataValue(NOVALUE)
            outDataset.SetGeoTransform(transform)
            return True
        except:
            QMessageBox.information(None,"Exiting gracefully","I can't write %s texture file." % outFile)
            return

    def loadTextureFile(self,outFile):
        "Load texture map in TOC"
        fileInfo = QFileInfo(outFile)
        baseName = fileInfo.baseName()
        rlayer = QgsRasterLayer(outFile, baseName)
        if not rlayer.isValid():
            self.textEdit.append("Layer failed to load!")
        rlayer.setDrawingStyle(QgsRasterLayer.SingleBandPseudoColor)
        rlayer.setColorShadingAlgorithm(QgsRasterLayer.FreakOutShader)
        QgsMapLayerRegistry.instance().addMapLayer(rlayer)



    def accept(self):
        "Called when 'OK' button pressed"

        AttributesGain=self.lineEditAttributesGain.text()
        AttributesCost=self.lineEditAttributesCost.text()
        Decision=self.lineEditDecision.text()

        ClassifiedMap=self.lineEditClassifiedMap.text()

        self.BuildFileISF(AttributesGain, AttributesCost, Decision, ClassifiedMap)

        #self.textEditLog.append(str(AttributesGain))


        #dataClay,dataSand,rows,cols,transform=self.ProcessRaster(sand,clay)
        #self.progressBar.setRange(0,rows)




